package com.myjob.serviceImpl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myjob.common.DubboConfig;
import com.myjob.config.Constants;
import com.myjob.config.MjServiceName;
import com.myjob.entity.*;
import com.myjob.exception.DBOptionException;
import com.myjob.handler.*;
import com.myjob.mapper.JobMapper;
import com.myjob.response.Result;
import com.myjob.service.JobService;
import com.myjob.utils.UtilValidate;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Chen Yuan
 * @create 2021-01-27  17:09
 */
@Service
@Slf4j
public class JobServiceImpl extends ServiceImpl<JobMapper, Job> implements JobService {
	@Autowired
	private JobMapper jobMapper;

	@Reference(group = MjServiceName.COMPANY, version = DubboConfig.VERSION)
	private CompanyHandler companyHandler;

	@Reference(group = MjServiceName.COMPANY, version = DubboConfig.VERSION)
	private HrHandler hrHandler;

	@Reference(group = MjServiceName.COMPANY, version = DubboConfig.VERSION)
	private MemberHandler memberHandler;

	@Override
	public Result selectAllJobs(Integer currentPage, Integer pageSize,
	                            String jobName, String hrName,
	                            Short salaryMin, Short salaryMax,
	                            String salaryUnit, String experience,
	                            String education, Integer deleted,
	                            String searchValue, String companyId, List<String> statusList,
	                            String companyOrHrId) {
		QueryWrapper<Job> wrapper = new QueryWrapper<>();
		Page<Job> page = null;

		if (UtilValidate.isNotEmpty(jobName)){
			wrapper.and(wrapper1 -> wrapper1.like("job_name", jobName)
					.or().like("job_type", jobName)
					.or().like("industry", jobName)
					.or().like("introduce", jobName)
					.or().like("requirement", jobName));
		}
		if (UtilValidate.isNotEmpty(hrName)){
			wrapper.like("hr_name", hrName);
		}
		if (UtilValidate.isNotEmpty(salaryMin)){
			wrapper.ge("salary_min", salaryMin);
		}
		if (UtilValidate.isNotEmpty(salaryMax)){
			wrapper.le("salary_max", salaryMax);
		}
		if (UtilValidate.isNotEmpty(salaryUnit)){
			wrapper.eq("salary_unit", salaryUnit);
		}
		if (UtilValidate.isNotEmpty(experience)){
			wrapper.eq("experience", experience);
		}
		if (UtilValidate.isNotEmpty(education)){
			wrapper.eq("education", education);
		}
		if (UtilValidate.isNotEmpty(deleted)){
			wrapper.eq("deleted", deleted);
		}
		if (UtilValidate.isNotEmpty(searchValue)) {
			wrapper.and(w -> w.like("job_name", searchValue)
							.or().like("job_type", searchValue)
							.or().like("industry", searchValue)
							.or().like("introduce", searchValue));
		}
		if (UtilValidate.isNotEmpty(companyId)) {
			wrapper.eq("company_id", companyId);
		}
		if (statusList != null && statusList.size() > 0){
			wrapper.in("job_status", statusList);
		}
		if (UtilValidate.isNotEmpty(companyOrHrId)) {
			wrapper.and(w -> w.eq("company_id", companyOrHrId)
							.or().eq("hr_id", companyOrHrId));
		}
		wrapper.orderByDesc("create_date");
		if (UtilValidate.isEmpty(pageSize)){
			page = new Page<>(currentPage, Constants.getPageSize());
		}else {
			page = new Page<>(currentPage, pageSize);
		}
		IPage<Job> jobs = jobMapper.selectPage(page, wrapper);
		return Result.succeed(jobs);
	}

	@Override
	public Result selectOneJob(String JobId, String companyId) {
		QueryWrapper<Job> wrapper = new QueryWrapper<>();
		wrapper.eq("job_id", JobId);
		Job job = jobMapper.selectOne(wrapper);

		log.info("[Dubbo] - 远程调用开始 -> "+MjServiceName.COMPANY+" -> companyHandler -> selectOneCompany");
		Company company = companyHandler.selectOneCompany(companyId);
		if (UtilValidate.isNotEmpty(company)){
			job.setCompany(company);
		}
		log.info("[Dubbo] - 远程调用结束 -> =======================================================");

		return Result.succeed(job);
	}

	@Override
	@GlobalTransactional(rollbackFor = {DBOptionException.class, RuntimeException.class})
	public int addJob(Job job) {
		if (UtilValidate.isEmpty(job)){
			return -1;
		}
		log.info("[Dubbo] - 远程调用开始 - 查询人事信息 -> "+MjServiceName.COMPANY+" -> hrHandler -> selectOneHr");
		Hr hr = hrHandler.selectOneHr(job.getHrId());
		log.info("[Dubbo] - 远程调用结束 -> ==============================================");
		log.info("[Dubbo] - 远程调用开始 - 查询人事对应的企业信息 -> "+MjServiceName.COMPANY+" -> companyHandler -> selectOneCompany");
		Company company = companyHandler.selectOneCompany(hr.getCompanyId());
		log.info("[Dubbo] - 远程调用结束 -> ==============================================");

		int updateNumber = updatePostNumber(1, hr.getCompanyId(), job.getHrId());

		job.setCompanyId(company.getCompanyId());
		job.setCompanyName(company.getCompanyName());

		job.setHrId(hr.getUserId());

		job.setJobStatus("正常");

		int insert = jobMapper.insert(job);
		return insert + updateNumber;
	}

	@Override
	@GlobalTransactional(rollbackFor = {DBOptionException.class, RuntimeException.class})
	public int updateJob(Job job, Integer number) {
		if (UtilValidate.isEmpty(job)){
			return -1;
		}
		int updateNumber = updatePostNumber(number, job.getCompanyId(), job.getHrId());
		if (updateNumber == -1){
			updateNumber = 2;
		}
		int update = jobMapper.updateById(job);
		return update + updateNumber;
	}

	@Override
	@GlobalTransactional(rollbackFor = {DBOptionException.class, RuntimeException.class})
	public int deleteJob(Job job) {
		if (UtilValidate.isEmpty(job)){
			return -1;
		}
		int updateNumber = updatePostNumber(-1, job.getCompanyId(), job.getHrId());

		int row = 0;
		if (Objects.equals(job.getDeleted(), Constants.getNoDel())){
			job.setDeleted(Constants.getYetDel());
			row = jobMapper.updateById(job);
		}else {
			row = jobMapper.deleteById(job.getJobId());
		}

		return row+updateNumber;
	}

	@Override
	public Result selectBookmarkList(Integer currentPage, Integer pageSize,
	                                 String searchValue, List<String> bookmarkList) {
		QueryWrapper<Job> wrapper = new QueryWrapper<>();
		wrapper.in("job_id", bookmarkList);

		if (UtilValidate.isNotEmpty(searchValue)) {
			wrapper.and(w -> w.like("job_name", searchValue));
		}

		Page<Job> page = null;
		if (UtilValidate.isNotEmpty(pageSize)) {
			page = new Page<>(currentPage, pageSize);
		}else {
			page = new Page<>(currentPage, Constants.getPageSize());
		}
		IPage<Job> iPage = jobMapper.selectPage(page, wrapper);
		return Result.succeed(iPage, "查询收藏的企业信息成功");
	}

	@Override
	public Result countJob() {
		Integer integer = jobMapper.selectCount(null);
		if (UtilValidate.isNotEmpty(integer)) {
			return Result.succeed(integer, "查询成功");
		}else {
			return Result.failed("查询失败");
		}
	}

	/**
	 * 修改 企业、hr 信息之中的 发布岗位个数
	 * @param number 岗位增加数量，如果减少则传入负数
	 * @param companyId 企业编号
	 * @param hrId 人事编号
	 * @return
	 */
	@GlobalTransactional(rollbackFor = {DBOptionException.class, RpcException.class, RuntimeException.class})
	public int updatePostNumber(int number, String companyId, String hrId){
		if (UtilValidate.isEmpty(number)){
			return -2;
		}
		if (number == 0){
			return -1;
		}

		Company company = companyHandler.selectOneCompany(companyId);
		if (UtilValidate.isEmpty(company)) {
			return -2;
		}

		log.info("[Dubbo] - 远程调用开始 - 查询会员信息 -> "+MjServiceName.COMPANY+" -> memberHandler -> selectOneMember");
		Member member = memberHandler.selectOneMember(company.getMemberLevel());
		if (UtilValidate.isEmpty(member)) {
			return -2;
		}
		log.info("[Dubbo] - 远程调用结束 -> ===================================================");

		if (number > 0 && Objects.equals(company.getPostNumber(), member.getPostNumber())){
			return -3;
		}

		log.info("[Dubbo] - 远程调用开始 - 修改企业的岗位发布数 -> "+MjServiceName.COMPANY+" -> companyHandler -> updateCompany");
		if (company.getPostNumber() + number >= 0){
			company.setPostNumber(company.getPostNumber() + number);
		}
		int updateCompany = companyHandler.updateCompany(company);
		log.info("[Dubbo] - 远程调用结束 -> ==============================================");

		log.info("[Dubbo] - 远程调用开始 - 修改人事的岗位发布数 -> "+MjServiceName.COMPANY+" -> hrHandler -> updateHr");
		Hr hr = hrHandler.selectOneHr(hrId);
		if (hr.getJobNumber() + number >= 0){
			hr.setJobNumber(hr.getJobNumber() + number);
		}
		int updateHr = hrHandler.updateHr(hr);
		log.info("[Dubbo] - 远程调用结束 -> ==============================================");

		return updateCompany + updateHr;
	}



}
